using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Prism.Interactivity.InteractionRequest;

namespace PrismInteractionLack
{

	/// <summary>
	/// it3xl.com: It makes no sense to solve the bug.
	/// From http://compositewpf.codeplex.com/workitem/8532
	/// </summary>
	/// <typeparam name="T"></typeparam>
    public class WeakInteractionRequest<T> : IInteractionRequest
        where T : Notification
    {
        IList<WeakReference> handlers = new List<WeakReference>();

        /// <summary>
        /// Fired when interaction is needed.
        /// </summary>
        public event EventHandler<InteractionRequestedEventArgs> Raised
        {
            add
            {
                handlers.Add(new WeakReference(value));
            }

            remove
            {
                handlers.Remove(handlers.Where(e => e.Target as EventHandler<InteractionRequestedEventArgs> == value).FirstOrDefault());
            }
        }

        /// <summary>
        /// Fires the Raised event.
        /// </summary>
        /// <param name="context">The context for the interaction request.</param>
        //[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
        public void Raise(T context)
        {
            this.Raise(context, c => { });
        }

        /// <summary>
        /// Fires the Raised event.
        /// </summary>
        /// <param name="context">The context for the interaction request.</param>
        /// <param name="callback">The callback to execute when the interaction is completed.</param>
        //[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
        public void Raise(T context, Action<T> callback)
        {
            foreach (var handler in handlers)
            {
                if (handler.IsAlive)
                {
                    var myHandler = handler.Target as EventHandler<InteractionRequestedEventArgs>;
                    myHandler(this, new InteractionRequestedEventArgs(context, () => callback(context)));
                }
            }
        }
    }
}